// #include <limits.h>  // for uint_max
#include "crc_buf.h"
//这句话总忘
#define minCRC(x,y) ({\
    typeof(x) _x = x;\
    typeof(y) _y = y;\
    (void)(&_x == &_y);\
    _x > _y ? _y : _x;\
})

static inline int is_power_of_two(uint32_t num ) {
    if(num < 2) return 0;
    return num & (num - 1);
}

static inline uint32_t roundup_power_of_two(uint32_t num) {
    int i = 0;
    if(num < 2)
        return 2;
    for(; num > 0;i++)
        num = num>>1;
    return 1U<<i; //这里是U后缀
}

void buffer_report_to_tty(buffer_t *p, struct tty_port *tport, uint32_t sz) {
    uint32_t bytes_to_send, first_part, second_part;
    uint32_t i;
    // 如果缓冲区为空，直接返回
    if (rb_isempty(p)) {
        return;
    }

    // 确定实际可上报的数据量
    bytes_to_send = minCRC(sz, buffer_len(p));
    
    // 计算从环形缓冲区中分两部分读取数据的字节数
    first_part = minCRC(bytes_to_send, p->size - (p->head & (p->size - 1)));
    second_part = bytes_to_send - first_part;

    // 第一部分：从缓冲区 head 开始读取
    for (i = 0; i < first_part; i++) {
        tty_insert_flip_char(tport, p->buf[(p->head + i) & (p->size - 1)], TTY_NORMAL);
    }

    // 第二部分：如果数据跨越缓冲区末尾，从缓冲区头开始读取
    for (i = 0; i < second_part; i++) {
        tty_insert_flip_char(tport, p->buf[i], TTY_NORMAL);
    }

    // 更新缓冲区的 head 指针
    p->head += bytes_to_send;

    // 通知行规程刷新
    tty_flip_buffer_push(tport);
}

buffer_t * buffer_new(uint32_t sz) {
    buffer_t* buf = NULL;
    if(!is_power_of_two(sz))    
        sz = roundup_power_of_two(sz);
    buf = (buffer_t *)kmalloc(sizeof(buffer_t) + sz,__GFP_NORETRY);
    if (!buf) {
        return NULL;
    }
    buf->size = sz;
    buf->head = buf->tail = 0;
    buf->buf = (uint8_t *)(buf + 1);
    return buf;
}
/*放心他俩差不出大循环*/
uint32_t rb_len(buffer_t *r) {
    if(r->tail >= r->head) {
        return r->tail - r->head;
    } else { //为什么会有else 想象一下head走到int323最大值了
        return r->size - (r->head - r->tail);
    }
}
void buffer_free(buffer_t *r) {
    kfree(r);
    r = NULL;
}
uint32_t buffer_len(buffer_t *r) {
    return rb_len(r);
}

// 为什么这个不用考虑tail溢出了 因为又溢出回去了
//! 所以后面的程序大胆写就行
uint32_t rb_remain(buffer_t *r) {
    return r->size - r->tail + r->head;  // 计算剩余可用空间。
}
uint32_t rb_isempty(buffer_t *r) {
    return r->tail == r->head;
}
uint32_t rb_isfull(buffer_t *r) {
    return rb_remain(r) == 0 ? 1 : 0;
}
//add put 函数
uint32_t buffer_add(buffer_t *r, const void __user *data,uint32_t sz) {
    uint32_t i;
    if(sz > rb_remain(r))
        return 0;
    // 这个是尾部能插入多少
    // 因为是2的n次方所以r->tail回到0也可以意味着到头了
    // 65536 除不尽谁吧你就说
    i = minCRC(sz,r->size - (r->tail &(r->size - 1)));
   // 从用户空间拷贝数据到内核缓冲区（第一部分）
    if (copy_from_user(r->buf + (r->tail & (r->size - 1)), data, i)) {
        return 0;  // 如果拷贝失败，返回 0
    }

    // 从用户空间拷贝数据到内核缓冲区（第二部分，如果数据跨越环形缓冲区的尾部）
    if (copy_from_user(r->buf, data + i, sz - i)) {
        return 0;  // 如果拷贝失败，返回 0
    }
    r->tail += sz;
    return 0;
}
uint32_t buffer_remove(buffer_t *r, void __user *buf, uint32_t sz) {
    uint32_t i;
    if(rb_isempty(r))
        return 0;
    sz = minCRC(sz, r->tail - r->head); // 只能读这么多
    i = minCRC(sz,r->size - (r->head & (r->size - 1)));
    if (copy_to_user(buf, r->buf + (r->head & (r->size - 1)), i)) {
        return 0;  // 拷贝失败，返回 0
    }
    if (copy_to_user(buf + i, r->buf, sz - i)) {
        return 0;  // 拷贝失败，返回 0
    }
    r->head += sz;
    return sz;
}